﻿#include "line_item.h"
#include <QPen>
#include <QPainter>
#include <qmath.h>
#include <Qdebug>

Line_Object::Line_Object(PlugObject* startItem, SocketObject* endItem, Line_Object* parent)
    : QGraphicsLineItem(parent), myStartItem(startItem), myEndItem(endItem)
{
    //初始颜色A
    this->mylinecolor = QColor(255, 128, 64);
    //状态颜色
    this->Color_Similar = QColor(209, 186, 116);//颜色B
    this->Color_Connected = QColor(140, 199, 181);//颜色C

    this->isMoving = false;
    this->isDisConnnecting = false;
    this->isConnecting = false;
    this->isConnected = false;

    setFlag(QGraphicsItem::ItemIsSelectable);//启用图形项的选择性
    //设置最高层
    setZValue(1);
}

Line_Object::~Line_Object()
{

}

QRectF Line_Object::boundingRect() const
{
    //确定包围线段的矩形框
    qreal extra = (pen().width() + 18) / 2.0;
//    下面注释的做法为什么会报错
//    QPainterPath path = shape();
//    return  path.boundingRect().adjusted(-extra,-extra,extra,extra);
//    返回的是基于直线起点的，以xy坐标差为矩形边界的一个碰撞边界
    return QRectF ( line().p1(), QSizeF( line().p2().x() - line().p1().x(),  line().p2().y() - line().p1().y() ) )
           .normalized().adjusted(-extra, -extra, extra, extra);
}

//这里写了被选中函数，因此能够被继承
void Line_Object::drawSelectedRect(QPainter* painter)
{

    QRectF rect = this->boundingRect();
    painter->setPen(QPen(QColor(14, 14, 255), 1, Qt::DashLine)); //采用虚线绘制相应的选中框
    painter->setBrush(Qt::NoBrush);
    //虚线框的绘制，分别向左上角和右下角扩张一个单位
    painter->drawRect(rect.adjusted(-1, -1, 1, 1));
}


//shape 函数，返回精确边界值
QPainterPath Line_Object::shape() const
{
    QPainterPath path = QGraphicsItem::shape();
    path.moveTo(line().p1());
    path.lineTo(line().p2());
    path.addPolygon(arrowHead);
    return path;
}


void Line_Object::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
    Q_UNUSED(option);
    Q_UNUSED(widget);

    if(myStartItem->collidesWithItem(myEndItem))
        return;

    setPen(QPen(mylinecolor, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));  //颜色、宽度、实线、线条的末端样式，线条的连接样式
    //这里就直接调用了构造函数中pen的性质
    QPen mypen = pen();
//    mypen.setColor(Qt::black);

    painter->setPen(mypen);
    painter->setBrush(mylinecolor);

    //创建了中心连线的点坐标,这里的前者的item坐标可能不在中心
    //这里要使用maptoscene来实现图上的绘制
    setLine(QLineF(myStartItem->mapToScene(pos()), myEndItem->mapToScene(pos())));


    //绘制连线的箭头
    qreal arrowSize = 20;
    double angle = std::atan2(-line().dy(), line().dx()); //极端线段的角度
    QPointF arrowP1 = line().p2() + QPointF(-sin(angle + M_PI / 3) * arrowSize,
                                            -cos(angle + M_PI / 3) * arrowSize);
    QPointF arrowP2 = line().p2() + QPointF(-sin(angle + 2 * M_PI / 3) * arrowSize,
                                            -cos(angle + 2 * M_PI / 3) * arrowSize);

    arrowHead.clear();//需要先清空前面获取过的箭头坐标
    arrowHead << line().p2() << arrowP1 << arrowP2;//将箭头的三个坐标都添加到arrowHead的坐标列表中去

    painter->drawLine(line());//绘制线段
    painter->drawPolygon(arrowHead);//绘制箭头头部，由前面的三个点构成

    if(this->isSelected())
        drawSelectedRect(painter);
}


//改变箭头连接的状态
void Line_Object::judgeLineState()
{
    if(isMoving && isConnecting)
        lineState = "Connnecting!";
    else if(isMoving && isDisConnnecting)
        lineState = "DisConnecting!";
    else if(!isMoving && isConnected)
        lineState = "Connected!";
    else
        return;
    qDebug() << isMoving << isConnecting << isDisConnnecting << isConnected;
}





